/** \file main.c
 *  Test the grammer written, Adapted from Jim Idle which is adpated from Java equivalent
 * \brief Driver file
 *  example, by Terence Parr
 * \author Mohamad Noureddine
 */

#include <iostream>
#include <MINILexer.h>
#include <MINIParser.h>
#include <util.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "PDTCodeGraph.h"


std::string elabels[] ={"IF", "Then","Else","WhileCond", "WhileBody","First","Second","Base","Stride"};//!< operation labels for edges
std::string nlabels[] ={"IF","While","<","<=",">",">=","==","->","XOR","!=","=","OR","AND","+","-","*","/","%","^",".","LIST","[]","INT","PAIR","Array","CONST","CUSTOM","+","-","~"}; //!< operation labels for nodes

using namespace std;
//using namespace boost;


/** 
 * \brief traverse and generate the graph 

void traverseGraph(wikiGraph* //!< Graph of the code written
		   ,map<int,string> * //!< maps node_ID to variable_ID
		   );
*/

// Main entry point for this example
//
PDTCodeGraph * ANTLR3_CDECL
//mini_main	(int argc, char *argv[])
mini_main	(const string & inputFile)
{
#if 0
    bool dotFile=false;
    bool translate=false;
    string inputFile="";
    string inputState="";
    string outState="";
    int opt;

    while((opt = getopt(argc, argv, "i:dt:o:T"))!= -1){
        switch (opt) {
            case 'i':
                inputFile+=optarg;
                fName=(pANTLR3_UINT8)(inputFile.c_str());
                break;
            case 'd':
                dotFile=true;
                break;
            case 't':
                inputState+=optarg;
                break;
            case 'o':
                outState+=optarg;
                break;
            case 'T':
                translate=true;
                break;
            default:
                fprintf(stderr, "Usage: %s [-i {filename}] [-d generate dot] [-T translate] [-t {Input State}] [-o {Output State}]\n",
                        argv[0]);
                exit(EXIT_FAILURE);
        }
    }
#endif
    pANTLR3_UINT8 fName = (pANTLR3_UINT8)(inputFile.c_str());

    pANTLR3_INPUT_STREAM input = antlr3AsciiFileStreamNew(fName);
    if ( input == NULL)
    {
        fprintf(stderr, "Failed to open file %s\n", (char *)fName);
        exit(1);
    }

    pMINILexer lxr = MINILexerNew(input); // CLexerNew is generated by ANTLR
    if ( lxr == NULL )
    {
        fprintf(stderr, "Unable to create the lexer due to malloc() failure1\n");
        exit(1);
    }

    pANTLR3_COMMON_TOKEN_STREAM tstream = antlr3CommonTokenStreamSourceNew(ANTLR3_SIZE_HINT, TOKENSOURCE(lxr));
    if (tstream == NULL)
    {
        fprintf(stderr, "Out of memory trying to allocate token stream\n");
        exit(1);
    }

    // Finally, now that we have our lexer constructed, we can create the parser
    //
    pMINIParser psr = MINIParserNew(tstream);  // CParserNew is generated by ANTLR3
    if (psr == NULL)
    {
        fprintf(stderr, "Out of memory trying to allocate parser\n");
        exit(ANTLR3_ERR_NOMEM);
    }
    cout<<"Starting Parsing"<<endl;
    MINIParser_translation_unit_return a =psr->translation_unit(psr);

    PDTCodeGraph * cg = a._cg;

    /*int numNodes = cg->nodes.size();
    for ( int i = 0 ; i < numNodes ; i++ ) {
    	PDTNode * node = cg->nodes[i];
    	if ((node->getParents()).empty()) {
    		stringstream ss ( stringstream::in | stringstream::out );
    		node->toString(ss);
    		cout << ss.str() << endl;
    	}
    }*/

    /*for (unsigned int i = 0; i < cg->nodes.size(); i++)
    {
    	PDTNode * node = cg->nodes[i];
    	if (node->getParents().size() == 0)
    		node->eval(*cg);
    }*/

    /*
       if(dotFile)
       {
       cout<<"Traversing Graph"<<endl;
       traverseGraph(new_graph.graph,new_graph.mapping);  
       }

    //Translate graph
    if(translate)
    {
    cout<<"Translating wikiGraph to generic type"<<endl;
    PDTCodeGraph * cg = wiki2cg( &new_graph );
    }
     */
    psr	    ->free  (psr);	    psr = NULL;
    tstream ->free  (tstream);	    tstream = NULL;
    lxr	    ->free  (lxr);	    lxr = NULL;
    input   ->close (input);	    input = NULL;

    return cg;
}
